#include "printf.h"
#include "console.h"
#include <stdarg.h>

// 数字转换为字符串
static void print_number(int num, int base, int sign) {
    if(base<=0){
        console_puts("wrong base input!");
        return;
    }
    char buf[16];
    char *digits = "0123456789ABCDEF";
    uint32 n;
    int negative = 0;
    char *ptr = buf;
    
    // 处理符号
    if (sign && num < 0) {
        negative = 1;
        n = -num;
    } else {
        n = num;
    }
    
    // 转换为字符串（逆序）
    do {
        *ptr++ = digits[n % base];
        n /= base;
    } while (n > 0);
    
    // 处理负数
    if (negative) {
        *ptr++ = '-';
    }
    
    // 逆序输出
    while (ptr > buf) {
        console_putc(*--ptr);
    }
}

// 64位数字转换为字符串（用于lx格式）
static void print_number64(uint64 num, int base, int sign) {
    if(base<=0){
        console_puts("wrong base input!");
        return;
    }
    char buf[32];
    char *digits = "0123456789abcdef";
    uint64 n;
    int negative = 0;
    char *ptr = buf;
    
    // 处理符号（对于64位，通常不需要处理负数，但保留接口一致性）
    if (sign && (int64)num < 0) {
        negative = 1;
        n = -(int64)num;
    } else {
        n = num;
    }
    
    // 转换为字符串（逆序）
    do {
        *ptr++ = digits[n % base];
        n /= base;
    } while (n > 0);
    
    // 处理负数
    if (negative) {
        *ptr++ = '-';
    }
    
    // 逆序输出
    while (ptr > buf) {
        console_putc(*--ptr);
    }
}

// 字符串输出
static void print_string(const char *s) {
    if (s == 0) {
        console_puts("(null)");
    } else {
        console_puts(s);
    }
}

// 指针输出
static void print_pointer(uint64 ptr) {
    console_putc('0');
    console_putc('x');
    
    if (ptr == 0) {
        console_putc('0');
        return;
    }
    
    // 十六进制输出
    char buf[16];
    char *digits = "0123456789abcdef";
    char *ptr_buf = buf;
    uint64 n = ptr;
    
    do {
        *ptr_buf++ = digits[n % 16];
        n /= 16;
    } while (n > 0);
    
    // 补零到8位（32位地址）
    while (ptr_buf - buf < 8) {
        *ptr_buf++ = '0';
    }
    
    // 逆序输出
    while (ptr_buf > buf) {
        console_putc(*--ptr_buf);
    }
}

// 主printf函数
int printf(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    
    for (int i = 0; fmt[i]; i++) {
        if (fmt[i] == '%') {
            i++;
            // 检查是否是lx格式
            if (fmt[i] == 'l' && fmt[i+1] == 'x') {
                i++; // 跳过'l'
                print_number64(va_arg(ap, uint64), 16, 0);
            } else {
                switch (fmt[i]) {
                    case 'd': // 十进制整数
                        print_number(va_arg(ap, int), 10, 1);
                        break;
                    case 'x': // 十六进制整数
                        print_number(va_arg(ap, int), 16, 0);
                        break;
                    case 'p': // 指针
                        print_pointer(va_arg(ap, uint64));
                        break;
                    case 's': // 字符串
                        print_string(va_arg(ap, char*));
                        break;
                    case 'c': // 字符
                        console_putc(va_arg(ap, int));
                        break;
                    case '%': // 百分号
                        console_putc('%');
                        break;
                    default:  // 未知格式符
                        console_putc('%');
                        console_putc(fmt[i]);
                        break;
                }
            }
        } else {
            console_putc(fmt[i]);
        }
    }
    
    va_end(ap);
    return 0;
}

// 数字转换为字符串到缓冲区（sprintf专用）
static int number_to_buffer(int num, int base, int sign, char *buf) {
    char digits[] = "0123456789ABCDEF";
    uint32 n;
    int negative = 0;
    int count = 0;
    char temp_buf[16];
    char *ptr = temp_buf;
    
    // 处理符号
    if (sign && num < 0) {
        negative = 1;
        n = -num;
    } else {
        n = num;
    }
    
    // 转换为字符串（逆序）
    do {
        *ptr++ = digits[n % base];
        n /= base;
    } while (n > 0);
    
    // 添加负号
    if (negative) {
        *ptr++ = '-';
    }
    
    // 逆序复制到目标缓冲区
    while (ptr > temp_buf) {
        *buf++ = *--ptr;
        count++;
    }
    
    return count;
}

// 64位数字转换为字符串到缓冲区（sprintf专用）
static int number64_to_buffer(uint64 num, int base, int sign, char *buf) {
    char digits[] = "0123456789abcdef";
    uint64 n;
    int negative = 0;
    int count = 0;
    char temp_buf[32];
    char *ptr = temp_buf;
    
    // 处理符号
    if (sign && (int64)num < 0) {
        negative = 1;
        n = -(int64)num;
    } else {
        n = num;
    }
    
    // 转换为字符串（逆序）
    do {
        *ptr++ = digits[n % base];
        n /= base;
    } while (n > 0);
    
    // 添加负号
    if (negative) {
        *ptr++ = '-';
    }
    
    // 逆序复制到目标缓冲区
    while (ptr > temp_buf) {
        *buf++ = *--ptr;
        count++;
    }
    
    return count;
}


// 字符串复制到缓冲区
static int string_to_buffer(const char *s, char *buf) {
    int count = 0;
    
    if (s == 0) {
        const char *null_str = "(null)";
        while (*null_str) {
            *buf++ = *null_str++;
            count++;
        }
    } else {
        while (*s) {
            *buf++ = *s++;
            count++;
        }
    }
    
    return count;
}

int sprintf(char *buf, const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    
    int total_chars = 0;
    
    for (int i = 0; fmt[i]; i++) {
        if (fmt[i] == '%') {
            i++;
            if (fmt[i] == '\0') break;
            
            // 检查是否是lx格式
            if (fmt[i] == 'l' && fmt[i+1] == 'x') {
                i++; // 跳过'l'
                uint64 num = va_arg(ap, uint64);
                int count = number64_to_buffer(num, 16, 0, buf);
                buf += count;
                total_chars += count;
            } else {
                switch (fmt[i]) {
                    case 'd': {
                        int num = va_arg(ap, int);
                        int count = number_to_buffer(num, 10, 1, buf);
                        buf += count;
                        total_chars += count;
                        break;
                    }
                    case 'x': {
                        int num = va_arg(ap, int);
                        int count = number_to_buffer(num, 16, 0, buf);
                        buf += count;
                        total_chars += count;
                        break;
                    }
                    case 's': {
                        char *str = va_arg(ap, char*);
                        int count = string_to_buffer(str, buf);
                        buf += count;
                        total_chars += count;
                        break;
                    }
                    case 'c': {
                        char c = va_arg(ap, int);
                        *buf++ = c;
                        total_chars++;
                        break;
                    }
                    case '%': {
                        *buf++ = '%';
                        total_chars++;
                        break;
                    }
                    default: {
                        *buf++ = '%';
                        *buf++ = fmt[i];
                        total_chars += 2;
                        break;
                    }
                }
            }
        } else {
            *buf++ = fmt[i];
            total_chars++;
        }
    }
    
    *buf = '\0';
    va_end(ap);
    return total_chars;
}

// 彩色printf函数
int printf_color(int color, const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    
    // 设置颜色
    console_set_color(color);
    
    // 使用现有的printf逻辑进行格式化输出
    for (int i = 0; fmt[i]; i++) {
        if (fmt[i] == '%') {
            i++;
            // 检查是否是lx格式
            if (fmt[i] == 'l' && fmt[i+1] == 'x') {
                i++; // 跳过'l'
                print_number64(va_arg(ap, uint64), 16, 0);
            } else {
                switch (fmt[i]) {
                    case 'd': {
                        int num = va_arg(ap, int);
                        print_number(num, 10, 1);
                        break;
                    }
                    case 'x': {
                        int num = va_arg(ap, int);
                        print_number(num, 16, 0);
                        break;
                    }
                    case 's': {
                        char *str = va_arg(ap, char*);
                        print_string(str);
                        break;
                    }
                    case 'c': {
                        char c = va_arg(ap, int);
                        console_putc(c);
                        break;
                    }
                    case '%': {
                        console_putc('%');
                        break;
                    }
                    default: {
                        console_putc('%');
                        console_putc(fmt[i]);
                        break;
                    }
                }
            }
        } else {
            console_putc(fmt[i]);
        }
    }
    
    // 重置颜色
    console_reset_color();
    
    va_end(ap);
    return 0;
}

// panic函数：打印错误信息并停止执行
void panic(const char *s) {
    printf("panic: %s\n", s);
    // 死循环，停止执行
    for(;;) {
        asm volatile("wfi");  // wait for interrupt
    }
}